package cn.kmsoft.jssc.controller;


import cn.kmsoft.common.ResInfo;
import cn.kmsoft.common.utils.StringUtil;
import cn.kmsoft.jssc.entity.analyse.AnalysePoint;
import cn.kmsoft.jssc.entity.analyse.AnalyseTable;
import cn.kmsoft.jssc.entity.analyse.CustomOverlay;
import cn.kmsoft.jssc.entity.analyse.SpatialOverlayParam;
import cn.kmsoft.wololo.object.query.AnalysisType;
import cn.kmsoft.stgeometry.util.*;
//import cn.kmsoft.utils.StringUtil;
import cn.kmsoft.wololo.object.GeoJson;
import cn.kmsoft.wololo.object.query.GeoJsonQuery;
import cn.kmsoft.wololo.object.query.GeoJsonQuery2;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Component
@RestController
@Api(description = "空间套合分析", tags = "3-Analyse Controller")
@RequestMapping(value = "/analyse")
public class AnalyseController extends BaseController {
    //private static final Logger logger = LoggerFactory.getLogger(AnalyseController.class);
    private final double areaScale = 10000;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss-SSS");

    @ApiOperation(value = "analysePoint", notes = "列出系统能提供的分析点集合")
    @RequestMapping(value = "/analysePoint", method= RequestMethod.GET)
    public ResInfo analysePoint(){
        ResInfo resInfo = new ResInfo();

        System.out.println();
        List<AnalysePoint> analysePoints = this.analyseConfig.getAnalysePoints();
        for (AnalysePoint analysePoint: analysePoints){
            System.out.println(analysePoint);
        }
        int size = analysePoints.size();
        String msg = String.format("-->analysePoint获取分析点列表成功, size: %d ",size);
        System.out.println(msg);
        log.info(msg);

        resInfo.setMsg("获取分析点列表成功");
        resInfo.setCode(200);
        resInfo.setStatus(ResInfo.SUCCESS);
        resInfo.setRes(null);
        resInfo.setData(analysePoints);
        return resInfo;
    }


    @ApiOperation(value = "shp2geoJson", notes = "获取默认geoJson对象")
    @RequestMapping(value = "/shp2geoJson", method= RequestMethod.GET)
    public ResInfo shp2geoJson(String shppath){
        ResInfo resInfo = new ResInfo();

        //3-shp2geojson
        //String geoJsonStr = GeoJsonQueryUtil.shp2GeoJsonStr(shppath);
        File shpfile= new File(shppath);
        if(!shpfile.exists()){
            String msg = String.format("-->shp2geoJson stoped,你传入的文件路径： %s 不存在",shppath);
            System.out.println(msg);
            log.info(msg);

            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setCode(500);
            resInfo.setMsg(msg);
            resInfo.setRes(null);

            return resInfo;
        }
        GeoJson geojson= Shapefile2GeoJson.shp2GeoJson(shppath);
        System.out.println();
        System.out.println(geojson);

        resInfo.setStatus(ResInfo.SUCCESS);
        resInfo.setCode(200);
        resInfo.setMsg("shp2GeoJson success! ");
        resInfo.setRes(geojson);
        resInfo.setData(geojson);

        return resInfo;
    }


    @ApiOperation(value = "shp2geoJsonQuery", notes = "获取默认geoJsonQuery对象")
    @RequestMapping(value = "/shp2geoJsonQuery", method= RequestMethod.GET)
    public ResInfo shp2geoJsonQuery(  String shppath){
        ResInfo resInfo = new ResInfo();

        //3-shp2geoquery
        File shpfile= new File(shppath);
        if( !shpfile.exists()){
            String msg = String.format("-->shp2geoJsonQuery stoped,你传入的文件路径： %s 不存在",shppath);
            System.out.println(msg);
            log.info(msg);

            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setCode(500);
            resInfo.setMsg(msg);
            resInfo.setRes(null);

            return resInfo;
        }
        //String geoQueryStr = GeoJsonQueryUtil.shp2GeoQueryStr(shppath, wkid);
        //GeoJsonQuery geoJsonQuery = GeoJsonQueryUtil.shp2GeoQuery(shppath, wkid);
        int wkid = 4524;
        String crsName = JTSGeometryWKTUtil.getShpCrsName(shppath);
        if(!StringUtil.isNullOrEmpty(crsName)){
            try {
                String wkidStr = CrsUtil.getWkidByCrsName(crsName);
                wkid= Integer.parseInt(wkidStr);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        GeoJsonQuery2 geoJsonQuery = GeoJsonQueryUtil.shp2GeoQuery2(shppath, wkid, AnalysisType.INTERSECT);
        System.out.println();
        System.out.println(JSON.toJSONString(geoJsonQuery));

        resInfo.setStatus(ResInfo.SUCCESS);
        resInfo.setCode(200);
        resInfo.setMsg("shp2GeoQuery success! ");
        resInfo.setRes(geoJsonQuery);
        resInfo.setData(geoJsonQuery);

        return resInfo;
    }


    @ApiOperation(value = "空间套合分析", notes = "根据analystCode进行空间套合分析。analystCode下可能有多个数据列表，例如输入dltb可实现所有现状的叠加分析")
    @RequestMapping(value = "/spatialOverlay", method= RequestMethod.POST)
    public ResInfo spatialOverlay(@RequestParam("projectId") String projectId,
                            @RequestParam("analystCode") String analystCode,
                            @RequestBody GeoJsonQuery geoJsonQuery ){
        ResInfo resInfo = new ResInfo();

        String jobId = UUID.randomUUID().toString();
        //1、解析跨域请求的参数
        if( geoJsonQuery == null || geoJsonQuery.getGeoJson() == null) {
            String msg= String.format("--->spatialOverlay stoped, 无图形，叠加分析终止,projectId: %s",projectId);
            //System.out.println(msg);
            log.info(msg);

            //无图形，叠加终止
            resInfo.setMsg(msg);
            resInfo.setStatus(ResInfo.FAIL);

            return resInfo;
        }
        Date startDTime = new Date();
        String startTimeStr = sdf.format(startDTime).toString();

        System.out.println();
        System.out.println();
        String msgStr = String.format("*************************spatialOverlay,空间套合分析开始!, projectId: %s, startTime: %s ******************",projectId,startTimeStr);
        //System.out.println(msgStr);
        log.info(msgStr);

        int wkid = geoJsonQuery.getWkid();
        //2、根据analyst获取不同的数据项图层表名
        List<AnalyseTable> analyseTables = this.getAnalyseTablesByAnalystCode(this.analyseConfig, analystCode);

        //3、SpatialOverlayParam
        SpatialOverlayParam customParam =  new SpatialOverlayParam();
        customParam.setAnalyseTables(analyseTables);
        customParam.setTaskId(jobId);
        customParam.setGeoJsonQuery(geoJsonQuery);
        customParam.setPhase(startTimeStr);

        //4、执行
        List<CustomOverlay> cusOverlayList = this.doOverlayAnalyst(projectId, customParam);

        String msgStr2 = String.format("--->spatialOverlay,空间套合分析结束!, projectId: %s",projectId);
        //System.out.println(msgStr2);
        log.info(msgStr2);

        if(cusOverlayList != null && cusOverlayList.size()>0 ) {
            resInfo.setStatus(ResInfo.SUCCESS);
            resInfo.setCode(200);
            resInfo.setMsg("--->spatialOverlay空间套合分析完成");
            resInfo.setRes(cusOverlayList);
        }else {
            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setCode(500);
            resInfo.setMsg("--->spatialOverlay空间套合分析失败");
            resInfo.setRes(projectId);
        }

        return resInfo;
    }

    @ApiOperation(value = "空间套合分析1", notes = "根据analystCode和yearStr进行空间套合分析，一般情况下analystCode和yearStr会锁定在一个图层数据。analystCode列表可通过相关接口获取")
    @RequestMapping(value = "/spatialOverlay1", method= RequestMethod.POST)
    public ResInfo spatialOverlay1(@RequestParam("projectId") String projectId,
                                  @RequestParam("analystCode") String analystCode, @RequestParam("yearStr") String yearStr,
                                  @RequestBody GeoJsonQuery geoJsonQuery ){
        ResInfo resInfo = new ResInfo();

        String jobId = UUID.randomUUID().toString();
        //1、解析跨域请求的参数
        if( geoJsonQuery == null || geoJsonQuery.getGeoJson() == null) {
            String msg=String.format("--->spatialOverlay1 stoped, jobId: %s,无图形，叠加分析终止",projectId);
            //System.out.println(msg);
            log.info(msg);

            //无图形，叠加终止
            resInfo.setMsg(msg);
            resInfo.setStatus(ResInfo.FAIL);

            return resInfo;
        }

        Date startDTime = new Date();
        String startTimeStr = sdf.format(startDTime).toString();
        System.out.println();
        System.out.println();
        String msgStr = String.format("*************************spatialOverlay1,空间套合分析开始!, projectId: %s, startTime: %s ******************",projectId,startTimeStr);
        //System.out.println(msgStr);
        log.info(msgStr);

        //2、根据analystCode和yearStr获取对应的数据项图层表名
        List<AnalyseTable> analyseTables = this.getAnalyseTableByAnalystCodeAndYear(this.analyseConfig, analystCode,yearStr);

        //3、SpatialOverlayParam
        SpatialOverlayParam customParam =  new SpatialOverlayParam();
        customParam.setAnalyseTables(analyseTables);
        customParam.setTaskId(jobId);
        customParam.setGeoJsonQuery(geoJsonQuery);
        customParam.setPhase(startTimeStr);

        //4、执行
        List<CustomOverlay> cusOverlayList = this.doOverlayAnalyst(projectId, customParam);

        String msgStr2 = String.format("--->spatialOverlay1,空间套合分析结束!, projectId: %s",projectId);
        //System.out.println(msgStr2);
        log.info(msgStr2);

        if(cusOverlayList != null && cusOverlayList.size()>0 ) {
            resInfo.setStatus(ResInfo.SUCCESS);
            resInfo.setCode(200);
            resInfo.setMsg(String.format("--->spatialOverlay1,空间套合分析完成!,projectId: %s",projectId));
            resInfo.setRes(cusOverlayList);
        }else {
            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setCode(500);
            resInfo.setMsg(String.format("--->spatialOverlay1,空间套合分析失败!,projectId: %s",projectId));
            resInfo.setRes(projectId);
        }

        return resInfo;
    }


    @ApiOperation(value = "空间套合分析2", notes = "空间套合分析。同时传递多个analyseCodes并用逗号分割,遇到analyseCode多个年份图层问题，系统将只分析默认年份图层。")
    @RequestMapping(value = "/spatialOverlay2", method= RequestMethod.POST)
    public ResInfo spatialOverlay2(@RequestParam("projectId") String projectId,
                                  @RequestParam("analystCodes") String analystCodes,
                                  @RequestBody GeoJsonQuery geoJsonQuery ){
        ResInfo resInfo = new ResInfo();

        String taskId = UUID.randomUUID().toString();
        //1、解析跨域请求的参数
        if( geoJsonQuery == null || geoJsonQuery.getGeoJson() == null) {
            String msg = String.format("--->spatialOverlay2 stoped, projectId: %s, 无图形，叠加分析终止",projectId);
            //System.out.println(msg);
            log.info(msg);

            //无图形，叠加终止
            resInfo.setMsg(msg);
            resInfo.setStatus(ResInfo.FAIL);
            return resInfo;
        }

        Date startDTime = new Date();
        String startTimeStr = sdf.format(startDTime).toString();
        System.out.println();
        System.out.println();
        String msgStr = String.format("*************************spatialOverlay2,空间套合分析开始!, projectId: %s, startTime: %s ******************",projectId,startTimeStr);
        //System.out.println(msgStr);
        log.info(msgStr);

        //2、根据analyst获取不同的数据项图层表名
        List<AnalyseTable> analyseTables = new ArrayList<AnalyseTable>();
        List<String> analystCodeList = Arrays.asList(analystCodes.split(","));//将multiAnalyseCode进行分割，形成analystCode集合
        for (String analystCode: analystCodeList) {
            AnalyseTable analyseTable = this.getDefaultAnalyseTableByAnalystCode(this.analyseConfig, analystCode);
            if(analyseTable != null) {
                analyseTables.add(analyseTable);
            }
        }

        //3、SpatialOverlayParam
        SpatialOverlayParam customParam =  new SpatialOverlayParam();
        customParam.setAnalyseTables(analyseTables);
        customParam.setTaskId(taskId);
        customParam.setGeoJsonQuery(geoJsonQuery);
        customParam.setPhase(startTimeStr);

        //4、执行
        List<CustomOverlay> cusOverlayList = this.doOverlayAnalyst(taskId, customParam);

        String msgStr2 = String.format("--->spatialOverlay2,空间套合分析结束!, taskId: %s",taskId);
        //System.out.println(msgStr2);
        log.info(msgStr2);

        if(cusOverlayList != null && cusOverlayList.size()>0 ) {
            resInfo.setStatus(ResInfo.SUCCESS);
            resInfo.setCode(200);
            resInfo.setMsg(String.format("--->spatialOverlay2,空间套合分析完成!,projectId: %s",projectId));
            resInfo.setRes(cusOverlayList);
        }else {
            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setCode(500);
            resInfo.setMsg(String.format("--->spatialOverlay2,空间套合分析失败!,projectId: %s",projectId));
            resInfo.setRes(projectId);
        }

        return resInfo;
    }

    @ApiOperation(value = "高级空间套合分析", notes = "高级空间套合分析。lx包括base、advance、times")
    @RequestMapping(value = "/spatialOverlay3", method= RequestMethod.POST)
    public ResInfo spatialOverlay3(@RequestParam("projectId") String projectId,
                            @RequestParam("lx") String lx,
                            @RequestBody GeoJsonQuery geoJsonQuery ){
        ResInfo resInfo = new ResInfo();

        String taskId = UUID.randomUUID().toString();
        //1、解析跨域请求的参数
        if( geoJsonQuery == null || geoJsonQuery.getGeoJson() == null) {
            String msg = String.format("--->spatialOverlay3 stoped, projectId: %s, 无图形，叠加分析终止",projectId);
            //System.out.println(msg);
            log.info(msg);

            //无图形，叠加终止
            resInfo.setMsg(msg);
            resInfo.setStatus(ResInfo.FAIL);
            return resInfo;
        }
        Date startDTime = new Date();
        String startTimeStr = sdf.format(startDTime).toString();

        System.out.println();
        System.out.println();
        String msgStr = String.format("*************************spatialOverlay3,空间套合分析开始!, projectId: %s, startTime: %s ******************",projectId,startTimeStr);
        //System.out.println(msgStr);
        log.info(msgStr);

        //2、根据类型lx参数获取系统默认提供不同类别数据项图层的表名
        List<AnalyseTable> analyseTables = this.getAnalyseTablesByLx(this.analyseConfig, lx);

        //3、SpatialOverlayParam
        SpatialOverlayParam customParam =  new SpatialOverlayParam();
        customParam.setAnalyseTables(analyseTables);
        customParam.setTaskId(taskId);
        customParam.setGeoJsonQuery(geoJsonQuery);
        customParam.setPhase(startTimeStr);

        //4、执行空间叠加套合分析
        List<CustomOverlay> cusOverlayList = this.doOverlayAnalyst(taskId, customParam);

        String msgStr2 = String.format("--->spatialOverlay3,空间套合分析结束!, projectId: %s",projectId);
        //System.out.println(msgStr2);
        log.info(msgStr2);

        if(cusOverlayList != null && cusOverlayList.size()>0 ) {
            resInfo.setStatus(ResInfo.SUCCESS);
            resInfo.setCode(200);
            resInfo.setMsg(String.format("--->spatialOverlay3,空间套合分析完成, projectId: %s",projectId));
            resInfo.setRes(cusOverlayList);
        }else {
            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setCode(500);
            resInfo.setMsg(String.format("--->doOverlayAnalyst,高级空间套合分析失败, projectId: %s",projectId));
            resInfo.setRes(projectId);
        }

        return resInfo;
    }

    @ApiOperation(value = "自定义的空间叠加分析", notes = "自定义类型的空间叠加套合分析")
    @RequestMapping(value = "/customAnalyse", method= RequestMethod.GET)
    public ResInfo customAnalyse( @RequestBody SpatialOverlayParam customParam ){
        ResInfo resInfo = new ResInfo();

        String taskId = customParam.getTaskId();
        Date startDTime = new Date();
        String startTimeStr = sdf.format(startDTime).toString();

        System.out.println();
        System.out.println();
        String msgStr = String.format("*************************customAnalyse,空间套合分析开始!, taskId: %s, startTime: %s ******************",taskId,startTimeStr);
        //System.out.println(msgStr);
        log.info(msgStr);

        List<CustomOverlay> cusOverlayList = this.doOverlayAnalyst(taskId, customParam);

        String msgStr2 = String.format("--->customAnalyse,空间套合分析结束!, taskId: %s",taskId);
        //System.out.println(msgStr2);
        log.info(msgStr2);

        if(cusOverlayList != null && cusOverlayList.size()>0 ) {
            resInfo.setStatus(ResInfo.SUCCESS);
            resInfo.setCode(200);
            resInfo.setMsg("--->customAnalyse自定义空间套合分析完成");
            resInfo.setRes(cusOverlayList);
        }else {
            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setCode(500);
            resInfo.setMsg("--->customAnalyse自定义空间套合分析失败");
            resInfo.setRes(taskId);
        }

        return resInfo;
    }



}
